home *** CD-ROM | disk | FTP | other *** search
/ Workbench Design / WB Collection.iso / workbench werkzeuge / patches / fixslinks / fixslinks.c < prev    next >
C/C++ Source or Header  |  1996-04-07  |  6KB  |  279 lines

  1. /*
  2.  * fixslinks.c - Fix symlinks for several dos.library calls
  3.  *
  4.  * Author: Todd Vierling <amigagod@grove.ufl.edu>
  5.  *
  6.  * Do not link with startup code--compile and link as-is!
  7.  */
  8.  
  9. #include <proto/exec.h>
  10. #include <exec/execbase.h>
  11. #include <proto/dos.h>
  12. #include <dos/dosextens.h>
  13. #include <dos.h>
  14.  
  15. #define D1 register __d1
  16. #define D2 register __d2
  17. #define D3 register __d3
  18. #define D4 register __d4
  19. #define A0 register __a0
  20.  
  21. struct DosLibrary *DOSBase;
  22. char verstag[] = "\0$VER: fixslinks 0.5 (12.08.95) by Todd Vierling\n\0";
  23.  
  24. struct olddosfuncs {
  25.     __asm BPTR (*odf_Open)(D1 STRPTR,D2 LONG);
  26.     __asm BPTR (*odf_DeleteFile)(D1 STRPTR);
  27.     __asm BPTR (*odf_Lock)(D1 STRPTR,D2 LONG);
  28.     __asm BPTR (*odf_CreateDir)(D1 STRPTR);
  29.     __asm BPTR (*odf_LoadSeg)(D1 STRPTR);
  30.     __asm BPTR (*odf_SetComment)(D1 STRPTR,D2 STRPTR);
  31.     __asm BPTR (*odf_SetProtection)(D1 STRPTR,D2 LONG);
  32.     __asm BPTR (*odf_MakeLink)(D1 STRPTR,D2 LONG,D3 LONG);
  33.     __asm BPTR (*odf_NewLoadSeg)(D1 STRPTR,D2 struct TagItem *);
  34. } odf;
  35.  
  36. #define LVOOpen -0x1E
  37. #define LVODeleteFile -0x48
  38. #define LVOLock -0x54
  39. #define LVOCreateDir -0x78
  40. #define LVOLoadSeg -0x96
  41. #define LVOSetComment -0xB4
  42. #define LVOSetProtection -0xBA
  43. #define LVOMakeLink -0x1BC
  44. #define LVONewLoadSeg -0x300
  45.  
  46. void setfuncs(void);
  47. #define erronf (IoErr() == ERROR_OBJECT_NOT_FOUND)
  48.  
  49. /* This function must be first (entrypoint) */
  50.  
  51. __asm int START(void) {
  52.     if (!(DOSBase = (APTR)OpenLibrary("dos.library",37)))
  53.         return 50;
  54.     setfuncs();
  55.     PutStr("fixslinks 0.5 now active.\n");
  56.  
  57. /*
  58.  * This is one way to "wait forever safely". Later here will likely be put
  59.  * a WaitPort() to interpret locked-softlink packet calls.
  60.  */
  61.  
  62.     for (;;) {
  63.         Wait(0x80000000);
  64.         SetSignal(0,0x80000000);
  65.     }
  66.     return 0;
  67. }
  68.  
  69. __asm BPTR lockpathbut1(A0 char **pathptr) {
  70.     register char *path = *pathptr;
  71.     BPTR cdir, newlock;
  72.     char pathpart[36];
  73.     register int i;
  74.  
  75.     if (!path) {
  76.         SetIoErr(122);
  77.         return NULL;
  78.     }
  79.  
  80.     cdir = CurrentDir(NULL);
  81.     newlock = DupLock(cdir);
  82.     if (!*path)
  83.         return newlock;
  84.  
  85.     for (;;) {
  86.         CurrentDir(newlock);
  87.         for (i = 0; i < 32; i++) {
  88.             pathpart[i] = *path++;
  89.             if (!pathpart[i] || pathpart[i] == '/' ||
  90.                 pathpart[i] == ':')
  91.                 goto gotpath;
  92.         }
  93.         while (*path && *path != ':' && *path != '/')
  94.             ++path;
  95.         ++path;
  96.         gotpath:
  97.         if (!path[-1])
  98.             return cdir;
  99.  
  100.         *pathptr = path;
  101.         pathpart[i+1] = 0;
  102.         if (!(newlock = (*odf.odf_Lock)(pathpart,SHARED_LOCK))) {
  103.             UnLock(CurrentDir(cdir));
  104.             return NULL;
  105.         }
  106.         UnLock(CurrentDir(NULL));
  107.     }
  108. }
  109.  
  110. __asm BPTR SLOpen(D1 STRPTR nameptr, D2 LONG mode) {
  111.     BPTR cdir, rc;
  112.     char *name = nameptr;
  113.  
  114.     if (!(rc = (*odf.odf_Open)(name,mode)) && erronf) {
  115.         if (!(cdir = lockpathbut1(&name)))
  116.             return NULL;
  117.         rc = (*odf.odf_Open)(name,mode);
  118.         UnLock(CurrentDir(cdir));
  119.     }
  120.     return rc;
  121. }
  122.  
  123. __asm LONG SLDeleteFile(D1 STRPTR nameptr) {
  124.     BPTR cdir;
  125.     LONG rc;
  126.     char *name = nameptr;
  127.  
  128.     if (!(rc = (*odf.odf_DeleteFile)(name)) && erronf) {
  129.         if (!(cdir = lockpathbut1(&name)))
  130.             return 0;
  131.         rc = (*odf.odf_DeleteFile)(name);
  132.         UnLock(CurrentDir(cdir));
  133.     }
  134.     return rc;
  135. }
  136.  
  137. /*
  138.  * __asm LONG SLRename(D1 STRPTR oldname, D2 STRPTR newname) {
  139.  * }
  140.  */
  141.  
  142. __asm BPTR SLLock(D1 STRPTR nameptr, D2 LONG type) {
  143.     BPTR cdir, rc;
  144.     char *name = nameptr;
  145.  
  146.     if (!(rc = (*odf.odf_Lock)(name,type)) && erronf) {
  147.         if (!(cdir = lockpathbut1(&name)))
  148.             return NULL;
  149.         rc = (*odf.odf_Lock)(name,type);
  150.         UnLock(CurrentDir(cdir));
  151.     }
  152.     return rc;
  153. }
  154.  
  155. __asm BPTR SLCreateDir(D1 STRPTR nameptr) {
  156.     BPTR cdir, rc;
  157.     char *name = nameptr;
  158.  
  159.     if (!(rc = (*odf.odf_CreateDir)(name)) && erronf) {
  160.         if (!(cdir = lockpathbut1(&name)))
  161.             return NULL;
  162.         rc = (*odf.odf_CreateDir)(name);
  163.         UnLock(CurrentDir(cdir));
  164.     }
  165.     return rc;
  166. }
  167.  
  168. /* This must preserve D1! A little SAS/C assumption is done here. */
  169.  
  170. __asm BPTR SLLoadSeg(D1 STRPTR nameptr) {
  171.     BPTR cdir, rc;
  172.     ULONG d1;
  173.     char *name = nameptr;
  174.  
  175.     if (!(rc = (*odf.odf_LoadSeg)(name)) && erronf) {
  176.         if (!(cdir = lockpathbut1(&name)))
  177.             return NULL;
  178.         rc = (*odf.odf_LoadSeg)(name);
  179.         d1 = getreg(REG_D1);
  180.         UnLock(CurrentDir(cdir));
  181.         putreg(REG_D1,d1);
  182.     }
  183.     return rc;
  184. }
  185.  
  186. __asm LONG SLSetComment(D1 STRPTR nameptr, D2 STRPTR comment) {
  187.     BPTR cdir, rc;
  188.     char *name = nameptr;
  189.  
  190.     if (!(rc = (*odf.odf_SetComment)(name,comment)) && erronf) {
  191.         if (!(cdir = lockpathbut1(&name)))
  192.             return NULL;
  193.         rc = (*odf.odf_SetComment)(name,comment);
  194.         UnLock(CurrentDir(cdir));
  195.     }
  196.     return rc;
  197. }
  198.  
  199. __asm LONG SLSetProtection(D1 STRPTR nameptr, D2 LONG protect) {
  200.     BPTR cdir, rc;
  201.     char *name = nameptr;
  202.  
  203.     if (!(rc = (*odf.odf_SetProtection)(name,protect)) && erronf) {
  204.         if (!(cdir = lockpathbut1(&name)))
  205.             return NULL;
  206.         rc = (*odf.odf_SetProtection)(name,protect);
  207.         UnLock(CurrentDir(cdir));
  208.     }
  209.     return rc;
  210. }
  211.  
  212. /*
  213.  * __asm LONG SLExecute(D1 STRPTR command, D2 BPTR file1, D3 BPTR file2) {
  214.  * }
  215.  */
  216.  
  217. __asm LONG SLMakeLink(D1 STRPTR nameptr, D2 LONG dest, D3 LONG soft) {
  218.     BPTR cdir, rc;
  219.     char *name = nameptr;
  220.  
  221.     if (!(rc = (*odf.odf_MakeLink)(name,dest,soft)) && erronf) {
  222.         if (!(cdir = lockpathbut1(&name)))
  223.             return NULL;
  224.         rc = (*odf.odf_MakeLink)(name,dest,soft);
  225.         UnLock(CurrentDir(cdir));
  226.     }
  227.     return rc;
  228. }
  229.  
  230. /*
  231.  * __asm LONG SLSystem(D1 STRPTR command, D2 struct TagItem *tags) {
  232.  * }
  233.  */
  234.  
  235. __asm BPTR SLNewLoadSeg(D1 STRPTR nameptr, D2 struct TagItem *tags) {
  236.     BPTR cdir, rc;
  237.     char *name = nameptr;
  238.  
  239.     if (!(rc = (*odf.odf_NewLoadSeg)(name,tags)) && erronf) {
  240.         if (!(cdir = lockpathbut1(&name)))
  241.             return NULL;
  242.         rc = (*odf.odf_NewLoadSeg)(name,tags);
  243.         UnLock(CurrentDir(cdir));
  244.     }
  245.     return rc;
  246. }
  247.  
  248. /*
  249.  * __asm LONG SLSetOwner(D1 STRPTR name, D2 LONG owner_info) {
  250.  * }
  251.  */
  252.  
  253. /*
  254.  * Pardon the (buuuuuurp!) 'getodfp' kludge, but it optimizes better this
  255.  * way under SAS/C as a far data model.
  256.  */
  257.  
  258. #define dosetfunc(x) \
  259.     odfp->odf_ ## x = SetFunction(\
  260.         dosbase, LVO ## x, (APTR)SL ## x)
  261.  
  262. struct olddosfuncs *getodfp(void) { return &odf; }
  263.  
  264. void setfuncs(void) {
  265.     APTR dosbase = DOSBase;
  266.     struct olddosfuncs *odfp = getodfp();
  267.  
  268.     dosetfunc(Lock);
  269.  
  270.     dosetfunc(Open);
  271.     dosetfunc(DeleteFile);
  272.     dosetfunc(CreateDir);
  273.     dosetfunc(LoadSeg);
  274.     dosetfunc(SetComment);
  275.     dosetfunc(SetProtection);
  276.     dosetfunc(MakeLink);
  277.     dosetfunc(NewLoadSeg);
  278. }
  279.